package tms.model;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * The PeopleList class is a singleton representing the people in the TMS
 * It extends AbstractModelObject and implements PropertyChangeListener
 * to allow the fire of property changes
 * 
 * @author Amer Alhalabi/Rolf Schmidt
 * @version 2.0
 * 
 */
public class PeopleList extends AbstractModelObject implements PropertyChangeListener {

	// header string for the csv export of the people
	private static final String HEADER_STRING = "Name,Hours,Tasks\n";

	// the only instance of the class
	private static PeopleList s_instance = null;

	// holds all Person objects
	private List<Person> peopleList = new ArrayList<Person>();

	/**
	 * getter of the only instance of the class
	 * 
	 * @return the only instance of the class
	 */
	public static PeopleList getInstance() {
		if (s_instance == null)
			s_instance = new PeopleList();
		return s_instance;
	}

	/**
	 * private constructor to prevent the creation the multiple instances of the
	 * class
	 */
	private PeopleList() {
	}

	/**
	 * a getter of people list
	 * 
	 * @return list of People assigned tasks
	 */
	public List<Person> getPeopleList() {
		return this.peopleList;
	}

	/**
	 * a setter for the people list.
	 * It fires property change (personList) so that any registered listener can
	 * receive the change event
	 * 
	 * @param personList
	 *            the personList to set
	 */
	public void setPeopleList(ArrayList<Person> peopleList) {
		List<Person> oldValue = this.peopleList;
		this.peopleList = peopleList;
		firePropertyChange("peopleList", oldValue, this.peopleList);
	}

	public void clear() {
		peopleList.clear();
		firePropertyChange("peopleList", null, this.peopleList);
	}

	public void addPerson(Person person) {
		if (person == null)
			return;
		if (peopleList.contains(person))
			return;
		peopleList.add(person);
		firePropertyChange("peopleList", null, this.peopleList);
	}

	/**
	 * save the people table to a CSV file
	 * 
	 * @param fileName
	 *            path to the file where the content of the people list will be
	 *            saved
	 * @return true if the file was saved successfully, false otherwise
	 */
	public Boolean saveCSVFile(String fileName) {
		// do not allow the filename to be empty or null
		if (fileName == null || fileName == "") {
			System.out.println("Invalid file name.");
			return false;
		}
		PrintWriter printOut = null;

		// add the header to the stringbuilder that will be written to the CSV
		// file
		StringBuilder sb = new StringBuilder(HEADER_STRING);

		try {
			printOut = new PrintWriter(fileName);

			// loop over the person objects and retrieve the name, hours, and
			// taskList of each one
			// separate each attribute with a comma
			// and add that to stringbuilder, which will written to the CSV file

			// note that the tasklist is also a comma separated list of task
			// names;
			// thus we are using \ as a separator between the taskList and the
			// other attributes
			for (Person person : peopleList) {
				sb.append(person.getName());
				sb.append(",");
				sb.append(person.getHours());
				sb.append(",");
				sb.append("\"" + person.getTasklist() + "\"");
				sb.append("\n");
			}
			printOut.print(sb);
		} catch (FileNotFoundException e) {
			System.out.println("File: " + fileName);
			System.out.println(e.getMessage());
			return false;
		} finally {
			printOut.close();
		}
		return true;
	}

	@Override
	/**
	 * Fires property change (personList) so that any registered listener can receive the change event 
	 */
	public void propertyChange(PropertyChangeEvent evt) {
		firePropertyChange("peopleList", null, peopleList);
	}

}